#ifndef MULTIBOOTINFO_HPP
#define MULTIBOOTINFO_HPP

#include <std/cstdint>
#include <std/cstddef>
namespace multiboot
{
	/*表示内核的a.out符号表数据的结构。
	addr是一个.out格式的nlist结构数组的大小（4字节无符号长）的物理地址，
	紧接着是数组本身，然后是一组以零结尾的ascii字符串的大小（4字节无符号长）
	（在这种情况下加上sizeof（无符号长）），最后是字符串集本身。*/
	struct AOutSyms
{
	size_t tabsize;
	size_t strsize;
	void* addr;
	uint32_t reserved;
};

struct Elf32Syms
{
	uint32_t num;//Number of entries.
	size_t size; //Size of each entry.
	void* addr;  //Address of the section header table.
	char** shndx;//String table used as the index of names.
};
struct MemoryRegion
{
	size_t size;
	uint64_t base_addr;
	uint64_t length;
	uint32_t type;
	static constexpr uint32_t validType{UINT32_C(1)};
};

//Holds information about a module that has been loaded by the bootloader alongside the kernel.
struct Module
{
	//The start address of the module.
	void* mod_start;
	void* mod_end;
	char* string;
	uint32_t reserved;
};

//这是多引导信息数据结构，引导加载程序通过它将重要信息传递给操作系统。操作系统可以选择使用或忽略结构的任何部分
struct MultibootInfo
{
	static_assert(sizeof(void*) == sizeof(uint32_t), "Addresses must be 32-bit");
	static_assert(sizeof(size_t) == sizeof(uint32_t), "Sizes must be 32-bit");
	uint32_t flags;
	size_t mem_lower;
	size_t mem_upper;
	uint32_t boot_device;
	char* cmdline;
	size_t mods_count;
	Module* mods_addr;

	union
	{
		AOutSyms a_out_syms;
		Elf32Syms elf32_syms;
	};
	size_t mmap_length;
	MemoryRegion* mmap_addr;
	size_t drives_length;
	void* drives_addr;
	uint32_t config_table;
	char* boot_loader_name;
	//Address of an APM table. See Advanced Power Management (APM) BIOS
	void* apm_table;
	uint32_t vbe_control_info;
	uint32_t vbe_mode_info;
	//Current video mode in the format specified in VBE 3.0.
	uint16_t vbe_mode;
	uint16_t vbe_interface_seg;
	uint16_t vbe_interface_off;
	uint32_t vbe_interface_len;
};
namespace InfoAvailable
{
enum InfoAvailable : uint32_t
{
	mem_bounds       = 1 << 0,
	boot_device      = 1 << 1,
	cmdline          = 1 << 2,
	mods             = 1 << 3,
	a_out_syms       = 1 << 4,
	elf32_syms       = 1 << 5,
	mmap             = 1 << 6,
	drives           = 1 << 7,
	config_table     = 1 << 8,
	boot_loader_name = 1 << 9,
	apm_table        = 1 << 10,
	vbe              = 1 << 11
};

} 
}
#endif